#include<reg52.h>    	//包含头文件，一般情况不需要改动，头文件包含特殊功能寄存器的定义

sbit IR=P3^2;  			//红外接口标志
sbit PWM1 = P3^3;
sbit PWM2 = P3^4;
sbit LED = P3^5;

unsigned char  irtime;	//红外用全局变量

bit irpro_ok,irok;

unsigned char IRcord[4];
unsigned char irdata[33];

unsigned char counter1;
unsigned char counter2;
unsigned char angle1=3;
unsigned char angle2=3;
//unsigned char flag = 1;

void TIM0init(void)//定时器0初始化
{
	TMOD=0x02;//定时器0工作方式2，TH0是重装值，TL0是初值
	TH0=0x00; //重载值
	TL0=0x00; //初始化值
	ET0=1;    //开中断
	TR0=1;
}
void tim0_isr (void) interrupt 1
{
	irtime++;  //用于计数2个下降沿之间的时间
}
void EX0_ISR (void) interrupt 0 //外部中断0服务函数
{
	static unsigned char  i;             //接收红外信号处理
	static bit startflag;                //是否开始处理标志位
	if(startflag)                         
	{
		if(irtime<63&&irtime>=33)//引导码 TC9012的头码，9ms+4.5ms
            i=0;
    		irdata[i]=irtime;//存储每个电平的持续时间，用于以后判断是0还是1
    		irtime=0;
    		i++;
   			if(i==33)
      		{
	  			irok=1;
				i=0;
	  		}
	}
	else
	{
		irtime=0;
		startflag=1;
	}
}


void EX0init(void)
{
	 IT0 = 1;   //指定外部中断0下降沿触发，INT0 (P3.2)
	 EX0 = 1;   //使能外部中断
	 EA = 1;    //开总中断
}
void Timer1_Init()
{
	TMOD=0X10;
	
	TL1=0X33;
	TH1=0XFE;
	
	TF1 = 0;
	TR1 = 1;
	ET1 = 1;
	EA = 1;
	PT1 = 1;
}
void Timer1_Routine() interrupt 3
{
	TR1 = 0;
	TL1=0X33;
	TH1=0XFE;
	
	counter1++;
	counter2++;
	if(counter1 >= 40)
		counter1 = 0;
	if(counter2 >= 40)
		counter2 = 0;
	if(counter2 < angle2)
		PWM2 = 1;
	else
		PWM2 = 0;
	if(counter1 < angle1)
		PWM1 = 1;
	else
		PWM1 = 0;
	
	TR1 = 1;
}
void Ir_work(void)//红外键值散转程序
{
   switch(IRcord[2])//判断第三个数码值
		{
			case 0X45: LED=1;break;//总开,CH-
			case 0X46: LED=0;break;//总关,CH
			case 0X4A: LED=1;break;//总开,9
			case 0X52: LED=0;break;//总关,8
			case 0X44: LED=1;break;//左开，PREV
			case 0X40: LED=0;break;//左关，NEXT
			case 0X07: LED=1;break;//右开，VOL-
			case 0X15: LED=0;break;//右关，VOL+
			case 0X5A: LED=1;break;//左开，6
			case 0X1C: LED=0;break;//左关，5
			case 0X5E: LED=1;break;//右开，3
			case 0X18: LED=0;break;//右关，2
			default:break;
		}
	  irpro_ok=0;//处理完成标志
}
void Ircordpro(void)//红外码值处理函数
{ 
	unsigned char i, j, k,cord,value;
	k=1;
	for(i=0;i<4;i++)      //处理4个字节
	{
		for(j=1;j<=8;j++) //处理1个字节8位
		{
			cord=irdata[k];
			if(cord>7)//大于某值为1，这个和晶振有绝对关系，这里使用12M计算，此值可以有一定误差
			value=value|0x80;
			if(j<8)
			{
				value>>=1;
			}
			k++;
		}
		IRcord[i]=value;
		value=0;     
	} 
	irpro_ok=1;//处理完毕标志位置1
}

void main(void)
{   
	Timer1_Init();
	EX0init(); //初始化外部中断
	//TIM0init();//初始化定时器
	
	while(1)//主循环
	{
		if(irok)                        //如果接收好了进行红外处理
		{   
			Ircordpro();
			irok=0;
		}
		if(irpro_ok)                   //如果处理好后进行工作处理，如按对应的按键后显示对应的数字等
		{
			Ir_work();
			
		}
	}
}
  
  